package cn.fl.mcr.service.impl;

import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.mcr.constant.McrApiConstant;
import cn.fl.mcr.service.IMcrCstBlackListService;
import cn.fl.mcr.transform.McrCstBlackListVOTransform;
import cn.fl.mcr.util.DesensitizationUtil;
import cn.fl.mcr.vo.McrCstBlackListExcelVO;
import cn.fl.mcr.vo.McrCstBlackListVO;
import cn.lb.framework.poi.excel.ExcelImportUtil;
import cn.lb.framework.poi.excel.entity.ImportParams;
import cn.lionbridgecapital.loan.model.base.Pager;
import cn.lionbridgecapital.loan.model.condition.McrCstBlackListQC;
import cn.lionbridgecapital.loan.model.dto.McrCstBlackListDTO;
import cn.lionbridgecapital.loan.service.api.IMcrCstBlackListApiService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import fl.customer.facade.customer.api.ICustomerApiService;
import fl.customer.facade.customer.api.ICustomerQueryApiService;
import fl.customer.facade.customer.condition.CstBscInfoQueryCondition;
import fl.customer.facade.customer.dto.CstBscInfoDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @Description: 客户小贷黑名单 客户端服务层接口实现
 * @Description: 业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get* 批量：batch* 查询集合：search*
 */
@Service
public class McrCstBlackListServiceImpl implements IMcrCstBlackListService {

	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(McrCstBlackListServiceImpl.class);

	/**
	 * 最大导入数量
	 */
	private static final int MAX_IMPORT_LIST_SIZE = 1000;
	
	/**
	 * 客户黑名单API服务
	 */
	@Autowired
	private IMcrCstBlackListApiService mcrCstBlackListApiService;
	/**
	 * 客户查询API服务
	 */
	@Autowired
	private ICustomerQueryApiService customerQueryApiService;
    @Autowired
    private ICustomerApiService customerApiService;

	@Override
	public McrCstBlackListVO selectById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "selectById", "主键参数不能为空!", CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "获取对象主键不能为空!");
		}

		McrCstBlackListDTO dto = mcrCstBlackListApiService.selectById(id);
		if(StringUtils.isNotBlank(dto.getCstNm())){
			dto.setCstNm(DesensitizationUtil.name(dto.getCstNm()));
		}
		return McrCstBlackListVOTransform.toVO(dto);
	}

	@Override
	public Long add(McrCstBlackListVO entity) throws BaseException{
		final String methodName = "add";
		if(null == entity){
			BaseLogUtils.info(logger, methodName, "新增对象不存在!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"新增对象不存在!");
		}
        if(null == entity.getCstId()){
            BaseLogUtils.info(logger, methodName, "客户ID为空!");
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"客户ID为空!");
        }
        if(entity.getForbiddenTm().compareTo(entity.getForbiddenEndTm()) != -1){
            BaseLogUtils.info(logger, methodName, "禁用时间大于禁用结束时间!");
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"禁用时间大于禁用结束时间!");
        }
        CstBscInfoDTO cstBscInfoDTO = customerQueryApiService.getCstBscInfoById(entity.getCstId());
        BaseLogUtils.info(logger,methodName,"查询客户信息.返回信息:"+JSONObject.toJSONString(cstBscInfoDTO));
        if(cstBscInfoDTO == null){
            BaseLogUtils.info(logger, methodName, "客户ID不存在!");
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"客户ID不存在!");
        }
        entity.setUsrId(cstBscInfoDTO.getUsrId());
        entity.setCstNm(cstBscInfoDTO.getCstNm());
        if(!validRepeat(entity.getCstId(), methodName)){
            BaseLogUtils.info(logger, methodName, "数据重复!");
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"数据重复!");
        }
        if(StringUtils.isBlank(entity.getForbiddenReason()) || entity.getForbiddenReason().length() > 100){
			BaseLogUtils.info(logger, methodName, "原因不合法!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"原因不合法!");
		}
		entity.setOpCd(McrApiConstant.MCR_BL_LIST_OP_TYPE_ADM);
		return mcrCstBlackListApiService.add(McrCstBlackListVOTransform.toDTO(entity));
	}

	@Override
	public boolean removeById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "removeById", "删除对象主键不能为空!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"删除对象主键不能为空!");
		}
		return mcrCstBlackListApiService.removeById(id);
	}
	
	/**
     * 删除
     * @param ids
     * @return
     */
    public boolean removeByIds(List<Long> ids)throws BaseException{
		if(CollectionUtils.isEmpty(ids)){
			BaseLogUtils.info(logger, "removeByIds", "删除主键参数集合不能为空!", CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"删除对象主键不能为空!");
		}
		return false;
    }

	@Override
	public boolean modify(McrCstBlackListVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "modify", "修改对象不能为空!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"修改对象不能为空!");
		}

		return mcrCstBlackListApiService.modify(McrCstBlackListVOTransform.toDTO(entity));
	}

	@Override
	public Pager searchListPage(Pager page) throws BaseException{
		if(null == page){
			page = new Pager();
		}
		Pager pager = mcrCstBlackListApiService.searchListPage(page);
		List<McrCstBlackListDTO> list = (List<McrCstBlackListDTO>) pager.getResultList();
		List<McrCstBlackListVO> voList = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(list)){
			for (McrCstBlackListDTO dto : list){
				if(StringUtils.isNotBlank(dto.getCstNm())){
					dto.setCstNm(DesensitizationUtil.name(dto.getCstNm()));
				}
				voList.add(McrCstBlackListVOTransform.toVO(dto));
			}
			BaseLogUtils.info(logger, "searchListPage","查询黑名单分页列表.返回信息:"+JSONObject.toJSONString(pager));
		}
		pager.setResultList(voList);
		return pager;
	}

	@Override
	public String importData(String realPath) throws BaseException {
		final String methodName = "getBlackListFile";
		if (StringUtils.isEmpty(realPath)){
			BaseLogUtils.error(logger,methodName,"获取附件信息.参数为空");
			throw new BaseException(BaseExceptionConstant.COMMON_0002,"参数为空");
		}
		List<McrCstBlackListExcelVO> list = null;
		List<McrCstBlackListDTO> listInsert = new ArrayList<>();
		StringBuilder errorMsg = new StringBuilder("");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			//读取excel 文件
			list = this.importXls(realPath);

            BaseLogUtils.info(logger,methodName,"获取文件信息.excel写入完毕:");
        }catch (BaseException ex){
            BaseLogUtils.error(logger,methodName,"获取文件信息.异常.ex:"+ex.getMessage(),ex);
            return "获取附件信息异常";
        }catch (Exception ex){
            BaseLogUtils.error(logger,methodName,"获取文件信息.异常.ex:"+ex.getMessage(),ex);
            return "获取附件信息异常";
        }
        if (CollectionUtils.isEmpty(list) || list.size() == 0){
            BaseLogUtils.info(logger,methodName,"小贷获取附件信息.excel未获取到参数");
            return "未获取到参数";
        }
        if(list.size() > MAX_IMPORT_LIST_SIZE){
            BaseLogUtils.info(logger,methodName,"小贷获取附件信息.数据量大于"+MAX_IMPORT_LIST_SIZE);
            return "数据量大于"+MAX_IMPORT_LIST_SIZE;
        }
        Map<String, StringBuilder> msgFlagMap = new HashMap<>();
        for (McrCstBlackListExcelVO vo: list){
            BaseLogUtils.info(logger,methodName,"文件读取信息："+ JSON.toJSONString(vo));
            if(StringUtils.isEmpty(vo.getCstId()) && StringUtils.isEmpty(vo.getCertNo())){
                return "客户ID、身份证号，必填一项！";
            }
            StringBuilder lineError= new StringBuilder("");
            boolean isError = false;
            McrCstBlackListDTO dto = new McrCstBlackListDTO();
            if(StringUtils.isNotEmpty(vo.getCstId())){
                lineError.append("客户ID：").append(vo.getCstId());
                try{
                    dto.setCstId(Long.valueOf(vo.getCstId()));
                    //校验客户ID
                    CstBscInfoDTO cstBscInfoDTO = customerQueryApiService.getCstBscInfoById(dto.getCstId());
                    if(cstBscInfoDTO == null){
                        lineError.append("，客户不存在");
                        isError = true;
                    }else {
                        dto.setUsrId(cstBscInfoDTO.getUsrId());
                        dto.setCstNm(cstBscInfoDTO.getCstNm());

                        msgFlagMap.put(vo.getCstId(), lineError);
                    }
                }catch (Exception e){
                    lineError.append("，客户ID不合法");
                    isError = true;
                    BaseLogUtils.error(logger,methodName,"根据客户ID查询客户信息.异常.ex:"+e.getMessage(),e);
                }
            }else {
                lineError.append("身份证号：").append(vo.getCertNo());
                CstBscInfoQueryCondition qc = new CstBscInfoQueryCondition();
                qc.setCertNo(vo.getCertNo());
                try{
                    List<CstBscInfoDTO> cstList = customerQueryApiService.searchCstBscInfoList(qc);
                    if(cstList == null || cstList.isEmpty()){
                        lineError.append("，客户不存在");
                        isError = true;
                    }else {
                        CstBscInfoDTO cstBscInfoDTO = cstList.get(0);
                        dto.setCstId(cstBscInfoDTO.getId());
                        dto.setUsrId(cstBscInfoDTO.getUsrId());
                        dto.setCstNm(cstBscInfoDTO.getCstNm());

                        msgFlagMap.put(cstBscInfoDTO.getId().toString(), lineError);
                    }
                }catch (Exception e){
                    lineError.append("，客户查询异常");
                    isError = true;
                    BaseLogUtils.error(logger,methodName,"根据身份证号查询客户信息.异常.ex:"+e.getMessage(),e);
                }
            }
                /*lineError.append("手机号：").append(vo.getMp());
                // 查询客户信息
                CstNpBscInfoQueryCondition qc = new CstNpBscInfoQueryCondition();
                qc.setMp1(vo.getMp());
                qc.setSysCd(PropertiesCacheUtils.getProperty(SystemConstant.FL_SERVICE_CD));
                qc.setOrgCd(PropertiesCacheUtils.getProperty(SystemConstant.FL_ORG_CD));
                try{
                    List<CstNpBscInfoDTO> cstNpList =  this.customerApiService.searchCstNpBscInfoWithMp(qc);
                    if(cstNpList == null || cstNpList.isEmpty()){
                        lineError.append("，客户不存在");
                        isError = true;
                    }else {
                        CstNpBscInfoDTO cstNpBscInfoDTO = cstNpList.get(0);
                        CstBscInfoDTO cstBscInfoDTO = customerQueryApiService.getCstBscInfoById(cstNpBscInfoDTO.getId());
                        dto.setCstId(cstBscInfoDTO.getId());
                        dto.setUsrId(cstBscInfoDTO.getUsrId());
                        dto.setCstNm(cstBscInfoDTO.getCstNm());

                        msgFlagMap.put(cstBscInfoDTO.getId().toString(), lineError);
                    }
                }catch (Exception e){
                    lineError.append("，客户查询异常");
                    isError = true;
                    BaseLogUtils.error(logger,methodName,"根据手机号查询客户信息.异常.ex:"+e.getMessage(),e);
                }*/

            dto.setBillId(vo.getBillId());
            dto.setForbiddenReason(vo.getForbiddenReason());
            dto.setIsValid(BaseConstant.IS_YESNO_YES);
            dto.setOpCd(McrApiConstant.MCR_BL_LIST_OP_TYPE_ADM);
            try {
                //校验时间
                if(StringUtils.isNotBlank(vo.getForbiddenTm()) && StringUtils.isNotBlank(vo.getForbiddenEndTm())){
                    dto.setForbiddenTm(sdf.parse(vo.getForbiddenTm()));
                    dto.setForbiddenEndTm(sdf.parse(vo.getForbiddenEndTm()));
                    if(dto.getForbiddenTm().compareTo(dto.getForbiddenEndTm()) != -1){
                        lineError.append("，禁用时间大于禁用结束时间");
                        isError = true;
                    }
                }else {
                    lineError.append("，禁用时间或结束时间为空");
                    isError = true;
                }
            }catch (ParseException e){
                lineError.append("，时间格式错误");
                isError = true;
            }
            //校验客户类型
            String cstTypeCdStr = vo.getCstTypeCd().trim();
            if("内部".equals(cstTypeCdStr)){
                dto.setCstTypeCd(McrApiConstant.MCR_BL_LIST_CST_TYPE_IN);
            }else if("外部".equals(cstTypeCdStr)){
                dto.setCstTypeCd(McrApiConstant.MCR_BL_LIST_CST_TYPE_OUT);
            }else if("物流".equals(cstTypeCdStr)){
                dto.setCstTypeCd(McrApiConstant.MCR_BL_LIST_CST_TYPE_LGS);
            }else {
                lineError.append("，客户类型错误");
                isError = true;
            }
            //校验原因
            if(StringUtils.isBlank(vo.getForbiddenReason()) || vo.getForbiddenReason().length() > 100){
                lineError.append("，原因不合法");
                isError = true;
            }
            if(isError){
                errorMsg.append(lineError).append("！");
            }else {
                listInsert.add(dto);
            }
        }

        String errorStr = errorMsg.toString();
        if(StringUtils.isNotBlank(errorStr)){
            BaseLogUtils.info(logger,methodName,"获取附件信息.错误信息:"+errorStr);
            return errorStr;
        }

        try{
            //插入数据库
            for (McrCstBlackListDTO dto : listInsert){
                if(validRepeat(dto.getCstId(), methodName)){
                    mcrCstBlackListApiService.add(dto);
                } else {
                    errorMsg.append(msgFlagMap.get(dto.getCstId().toString())).append("，数据已存在，未导入！");
                }
            }
        }catch (Exception e){
            BaseLogUtils.error(logger,methodName,"保存黑名单信息.异常.ex:"+e.getMessage(),e);
        }
		return errorMsg.toString();
	}

    /**
     * 校验数据是否存在，根据客户ID
     * @param cstId
     * @param methodName
     * @return
     */
	private boolean validRepeat(Long cstId, String methodName){
        McrCstBlackListQC qc = new McrCstBlackListQC();
        qc.setCstId(cstId);
        List<McrCstBlackListDTO> listData = mcrCstBlackListApiService.searchList(qc);
        BaseLogUtils.info(logger,methodName,"校验重复，查询黑名单信息.返回信息:"+JSONObject.toJSONString(listData));
        if(CollectionUtils.isEmpty(listData)){
           return true;
        }
        return false;
    }

	/**
	 * 获取Excel文件
	 * @param filePath 文件地址
	 * @return 文件参数
	 * @throws BaseException 业务数据
	 */
	private List<McrCstBlackListExcelVO> importXls(String filePath) throws BaseException {
		Long startTm = System.currentTimeMillis();
		BaseLogUtils.info(logger, "importXls", "小贷系统导入Excel：realPath:"+filePath, CurrentThreadContext.getCurrentUserName());
		ImportParams params = new ImportParams();
		params.setTitleRows(1);//标题占用行数
		params.setHeadRows(1);//表头占用行数
		params.setNeedSave(false);//是否保存文件

		List<McrCstBlackListExcelVO> list = null;
		File file = new File(filePath);
		if (file.exists()) {
			BaseLogUtils.info(logger, "importXls", "小贷系统导入Excel.文件存在");
			list = ExcelImportUtil.importExcel(file, McrCstBlackListExcelVO.class, params);
		}
		BaseLogUtils.info(logger, "importXls", "小贷系统导入Excel:" + list.size());
		Long endTm = System.currentTimeMillis();
		BaseLogUtils.info(logger, "importXls", "导入帐号.耗时：" + (endTm - startTm), CurrentThreadContext.getCurrentUserName());
		return list;
	}
}
